package org.jeecg.common.util;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.sql.DataSource;

import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.DataBaseConstant;
import org.jeecg.common.util.filter.FileTypeFilter;
import org.jeecg.common.util.oss.OssBootUtil;
import org.jeecgframework.poi.util.PoiPublicUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;

import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;

@Slf4j
public class CommonUtils {
	
	@Value(value = "${jeecg.path.upload}")
    private static String uploadpath;

   //中文正则
    private static Pattern ZHONGWEN_PATTERN = Pattern.compile("[\u4e00-\u9fa5]");
    
    public static void main(String [] args) {
    	String f="OB21100002_1638179432606.png";
    	String f1="OB21100002_1638179432606_thumbnail.png";
    	File saveFile = new File("C:\\Users\\jerryzhu\\Desktop\\新建文件夹\\"+f);
    	File saveThumbnailFile = new File("C:\\Users\\jerryzhu\\Desktop\\新建文件夹\\"+f1);
		try {
			Thumbnails.of(saveFile).size(296, 296).keepAspectRatio(false).outputQuality(1f).toFile(saveThumbnailFile);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}//不按比例，就按指定的大小进行缩放

    }

    public static String uploadOnlineImage(byte[] data,String basePath,String bizPath,String uploadType){
        String dbPath = null;
        String fileName = "image" + Math.round(Math.random() * 100000000000L);
        fileName += "." + PoiPublicUtil.getFileExtendName(data);
        try {
            if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
                File file = new File(basePath + File.separator + bizPath + File.separator );
                if (!file.exists()) {
                    file.mkdirs();// 创建文件根目录
                }
                String savePath = file.getPath() + File.separator + fileName;
                File saveFile = new File(savePath);
                FileCopyUtils.copy(data, saveFile);
                boolean isImage = imageCheck(saveFile);//检查该文件是不是图片
                if(isImage) {//如果是图片的话，在同一目录下生成一张缩略图
                	if(fileName.indexOf(".") != -1){//如果有后缀名
                		String thumbnailFileName = fileName.substring(0, fileName.lastIndexOf(".")) + "_" + "thumbnail" + fileName.substring(fileName.lastIndexOf("."));
                		String saveThumbnailPath =  file.getPath() + File.separator + thumbnailFileName;
                		File saveThumbnailFile = new File(saveThumbnailPath);
                		//Thumbnails.of(saveFile).scale(0.2f).toFile(saveThumbnailFile);//按比例缩小
                		//Thumbnails.of(fromPic).size(400,500).toFile(toPic);//变为400*300,遵循原图比例缩或放到400*某个高度
                		Thumbnails.of(saveFile).size(296, 296).keepAspectRatio(false).outputQuality(1f).toFile(saveThumbnailFile);//不按比例，就按指定的大小进行缩放
                		
                		//Thumbnails.of(fromPic).scale(1f).outputQuality(0.25f).toFile(toPic);//图片尺寸不变，压缩图片文件大小outputQuality实现,参数1为最高质量
                		//Thumbnails.of(fromPic).size(200,200).rotate(90).toFile(toPic);//旋转图片，rotate(角度),正数则为顺时针，负数则为逆时针
                		
                		/** //给图片加水印，watermark(位置，水印图，透明度)Positions.CENTER表示加在中间
    					Thumbnails.of(fromPic).size(400,400)
    					.watermark(Positions.CENTER,ImageIO.read(waterPic),0.5f)
    					.outputQuality(0.8f).toFile(toPic);
                		 */
                	}
                }
                
                dbPath = bizPath + File.separator + fileName;
            }else {
                InputStream in = new ByteArrayInputStream(data);
                String relativePath = bizPath+"/"+fileName;
                if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
                    dbPath = MinioUtil.upload(in,relativePath);
                }else if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
                    dbPath = OssBootUtil.upload(in,relativePath);
                }
            }
            if (dbPath.contains("\\")) {
            	dbPath = dbPath.replace("\\", "/");
			}
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dbPath;
    }

    /**
     * 判断文件名是否带盘符，重新处理
     * @param fileName
     * @return
     */
    public static String getFileName(String fileName){
        //判断是否带有盘符信息
        // Check for Unix-style path
        int unixSep = fileName.lastIndexOf('/');
        // Check for Windows-style path
        int winSep = fileName.lastIndexOf('\\');
        // Cut off at latest possible point
        int pos = (winSep > unixSep ? winSep : unixSep);
        if (pos != -1)  {
            // Any sort of path separator found...
            fileName = fileName.substring(pos + 1);
        }
        //替换上传文件名字的特殊字符
        fileName = fileName.replace("=","").replace(",","").replace("&","")
                .replace("#", "").replace("“", "").replace("”", "");
        //替换上传文件名字中的空格
        fileName=fileName.replaceAll("\\s","");
        return fileName;
    }

    // java 判断字符串里是否包含中文字符
    public static boolean ifContainChinese(String str) {
        if(str.getBytes().length == str.length()){
            return false;
        }else{
            Matcher m = ZHONGWEN_PATTERN.matcher(str);
            if (m.find()) {
                return true;
            }
            return false;
        }
    }

    /**
     * 统一全局上传
     * @Return: java.lang.String
     */
    public static String upload(MultipartFile file, String bizPath, String uploadType) {
        String url = "";
        if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
            url = MinioUtil.upload(file,bizPath);
        } else if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
            url = OssBootUtil.upload(file,bizPath);
        } else if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
        	url = uploadLocal(file,bizPath,uploadpath);
        }
        return url;
    }
    /**
     * 本地文件上传
     * @param mf 文件
     * @param bizPath  自定义路径
     * @return
     */
    public static String uploadLocal(MultipartFile mf,String bizPath,String uploadpath){
        try {
            //update-begin-author:liusq date:20210809 for: 过滤上传文件类型
            FileTypeFilter.fileTypeFilter(mf);
            //update-end-author:liusq date:20210809 for: 过滤上传文件类型
            String fileName = null;
            File file = new File(uploadpath + File.separator + bizPath + File.separator );
            if (!file.exists()) {
                file.mkdirs();// 创建文件根目录
            }
            String orgName = mf.getOriginalFilename();// 获取文件名
            orgName = CommonUtils.getFileName(orgName);
            if(orgName.indexOf(".") != -1){//如果有后缀名
                fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
            }else{
                fileName = orgName+ "_" + System.currentTimeMillis();
            }
            String savePath = file.getPath() + File.separator + fileName;
            File saveFile = new File(savePath);
            FileCopyUtils.copy(mf.getBytes(), saveFile);
            boolean isImage = imageCheck(saveFile);//检查该文件是不是图片
            System.out.println("isImage======================="+isImage);
            if(isImage) {//如果是图片的话，在同一目录下生成一张缩略图
            	if(fileName.indexOf(".") != -1){//如果有后缀名
            		String thumbnailFileName = fileName.substring(0, fileName.lastIndexOf(".")) + "_" + "thumbnail" + fileName.substring(fileName.lastIndexOf("."));
            		String saveThumbnailPath =  file.getPath() + File.separator + thumbnailFileName;
            		File saveThumbnailFile = new File(saveThumbnailPath);
            		//Thumbnails.of(saveFile).scale(0.2f).toFile(saveThumbnailFile);//按比例缩小
            		//Thumbnails.of(fromPic).size(400,500).toFile(toPic);//变为400*300,遵循原图比例缩或放到400*某个高度
            		Thumbnails.of(saveFile).size(296, 296).keepAspectRatio(false).toFile(saveThumbnailFile);//不按比例，就按指定的大小进行缩放
            		
            		//Thumbnails.of(fromPic).scale(1f).outputQuality(0.25f).toFile(toPic);//图片尺寸不变，压缩图片文件大小outputQuality实现,参数1为最高质量
            		//Thumbnails.of(fromPic).size(200,200).rotate(90).toFile(toPic);//旋转图片，rotate(角度),正数则为顺时针，负数则为逆时针
            		
            		/** //给图片加水印，watermark(位置，水印图，透明度)Positions.CENTER表示加在中间
					Thumbnails.of(fromPic).size(400,400)
					.watermark(Positions.CENTER,ImageIO.read(waterPic),0.5f)
					.outputQuality(0.8f).toFile(toPic);
            		 */
            	}
            }
            String dbpath = null;
            if(oConvertUtils.isNotEmpty(bizPath)){
                dbpath = bizPath + File.separator + fileName;
            }else{
                dbpath = fileName;
            }
            if (dbpath.contains("\\")) {
                dbpath = dbpath.replace("\\", "/");
            }
            return dbpath;
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return "";
    }

    /**
     * 统一全局上传 带桶
     * @Return: java.lang.String
     */
    public static String upload(MultipartFile file, String bizPath, String uploadType, String customBucket) {
        String url = "";
        if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
            url = MinioUtil.upload(file,bizPath,customBucket);
        }else{
            url = OssBootUtil.upload(file,bizPath,customBucket);
        }
        return url;
    }

    /** 当前系统数据库类型 */
    private static String DB_TYPE = "";
    private static DbType dbTypeEnum = null;

    /**
     * 全局获取平台数据库类型（作废了）
     * @return
     */
    @Deprecated
    public static String getDatabaseType() {
        if(oConvertUtils.isNotEmpty(DB_TYPE)){
            return DB_TYPE;
        }
        DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class);
        try {
            return getDatabaseTypeByDataSource(dataSource);
        } catch (SQLException e) {
            //e.printStackTrace();
            log.warn(e.getMessage(),e);
            return "";
        }
    }

    /**
     * 全局获取平台数据库类型（对应mybaisPlus枚举）
     * @return
     */
    public static DbType getDatabaseTypeEnum() {
        if (oConvertUtils.isNotEmpty(dbTypeEnum)) {
            return dbTypeEnum;
        }
        try {
            DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class);
            dbTypeEnum = JdbcUtils.getDbType(dataSource.getConnection().getMetaData().getURL());
            return dbTypeEnum;
        } catch (SQLException e) {
            log.warn(e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取数据库类型
     * @param dataSource
     * @return
     * @throws SQLException
     */
    private static String getDatabaseTypeByDataSource(DataSource dataSource) throws SQLException{
        if("".equals(DB_TYPE)) {
            Connection connection = dataSource.getConnection();
            try {
                DatabaseMetaData md = connection.getMetaData();
                String dbType = md.getDatabaseProductName().toLowerCase();
                if(dbType.indexOf("mysql")>=0) {
                    DB_TYPE = DataBaseConstant.DB_TYPE_MYSQL;
                }else if(dbType.indexOf("oracle")>=0 ||dbType.indexOf("dm")>=0) {
                    DB_TYPE = DataBaseConstant.DB_TYPE_ORACLE;
                }else if(dbType.indexOf("sqlserver")>=0||dbType.indexOf("sql server")>=0) {
                    DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
                }else if(dbType.indexOf("postgresql")>=0) {
                    DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
                }else if(dbType.indexOf("mariadb")>=0) {
                    DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB;
                }else {
                    log.error("数据库类型:[" + dbType + "]不识别!");
                    //throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }finally {
                connection.close();
            }
        }
        return DB_TYPE;

    }
    
    
    /**
     * 检查是否图片文件
     * @param file
     * @return
     */
    public static boolean imageCheck(File file){
    	 try {
    		 BufferedImage image = ImageIO.read(file);
             return image != null;
         } catch(IOException ex) {
             return false;
         }
    }
    
	/**
	 * 替换下面的特殊字符为空
	  \n 回车(\u000a) 
	  \t 水平制表符(\u0009) 
	  \s 空格(\u0008) 
	  \r 换行(\u000d)
	 * @param str
	 * @return
	 */
    public static String replaceBlank(String str) {
		String dest = "";
		if (str!=null) {
			Pattern p = Pattern.compile("\\s*|\t|\r|\n");
			Matcher m = p.matcher(str);
			dest = m.replaceAll("");
		}
		return dest;
	}
	
	
}